package com.example.myapplication2;

import static androidx.constraintlayout.helper.widget.MotionEffect.TAG;

import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Environment;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.TextView;



import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class collecting extends AppCompatActivity {
    class ppgdata{
        public float Green;
        public float Red;
        public long timestamp;
    }
    class accdata{
        public float x;
        public float y;
        public float z;
        public long timestamp;
    }
    class grydata{
        public float x;
        public float y;
        public float z;
        public long timestamp;
    }
    ArrayList<ppgdata> ppglist= new ArrayList<ppgdata>();
    ArrayList<accdata> acclist= new ArrayList<accdata>();
    ArrayList<grydata> grylist= new ArrayList<grydata>();
    private Button test;
    private TextView text;
    private TextView PPG;
    private TextView ACC;
    private TextView GRY;
    private int count1=0;
    private int count2=0;
    private int count3=0;
    private CountDownTimer timer;
    private SensorManager mSensorManager;
    private MySensorEventListener mMySensorEventListener;
    private float[] mAccelerometerReading = new float[3];
    private float[] mMagneticFieldReading = new float[3];
    private static  String ppgfile="PPG_time_duration.csv";
    private static  String accfile="ACC_time_duration.csv";
    private static  String gryfile="GRY_time_duration.csv";
    ActivityResultLauncher<String> permissionLauncher;
    public static final int PPG_SENSOR = 65572;
    @SuppressLint("MissingInflatedId")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        Log.d("",para.pause+"");
        ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_collecting);
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
//        permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission());
        permissionLauncher=registerForActivityResult(new ActivityResultContracts.RequestPermission(),result -> {});
        permissionLauncher.launch(android.Manifest.permission.BODY_SENSORS);
        text= (TextView) findViewById(R.id.text);
        PPG=(TextView) findViewById(R.id.btn_PPG);
        ACC=(TextView) findViewById(R.id.btn_ACC);
        GRY=(TextView) findViewById(R.id.btn_GRY);
        text.setText("开始计时");
        timer = new CountDownTimer(para.time*1000, 10) {

            public void onTick(long millisUntilFinished) {
                Log.d( "",millisUntilFinished / 1000 +"秒");
                text.setText("正在测量，还剩"+millisUntilFinished / 1000 + "秒");

            }

            public void onFinish() {

                text.setText("计时结束");
                Log.d("","pause!!!");
                Log.d("",para.pause+"");
                if(para.pause==0&&(!ppglist.isEmpty()||!acclist.isEmpty()||!grylist.isEmpty())){
                    String act=para.getAction();
                    para.pause=1;
                    para.retest+=1;

                    try{
                        File dir=new File(Environment.getExternalStorageDirectory(),"RawData");
                        if(!dir.exists()){
                            dir.mkdirs() ;
                        }
                        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
                        
                            
                        para.t = format.format(new Date());
                        
                        Log.d("","456!!!");
                        if(para.choose[0]==1) {

                            ppgfile = "ppg_" + para.t + "_" + para.time+"_"+act+"_"+para.retest+".csv";


                            File ppgf = new File(dir, ppgfile);
                            Log.d("","here1");
                            if (!ppgf.exists()) {
                                Log.d("","789!!!");
                                ppgf.createNewFile();
                            }
                            Log.d("","here2");
                            FileOutputStream os = new FileOutputStream(ppgf, true);

                            for (ppgdata a : ppglist) {
                                Log.d("",a.Green+","+a.Red+","+a.timestamp);
                                String s=a.Green+","+a.Red+","+a.timestamp+"\n";
                                os.write(s.getBytes());
                                os.flush();
                            }
                            ppglist.clear();


                            os.close();

                        }
                        if(para.choose[1]==1) {
                            accfile = "acc_" + para.t + "_" + para.time+"_"+act+"_"+para.retest+".csv";
                            File accf = new File(dir, accfile);
                            if (!accf.exists()) {
                                accf.createNewFile();
                                FileOutputStream os = new FileOutputStream(accf, true);

                                for (accdata a : acclist) {
                                    String s=a.x+","+a.y+","+a.z+","+a.timestamp+"\n";
                                    os.write(s.getBytes());
                                    os.flush();
                                }
                                acclist.clear();
                                os.close();
                            }
                        }
                        if(para.choose[2]==1){
                            gryfile="gry_"+para.t+"_"+para.time+"_"+act+"_"+para.retest+".csv";
                            File gryf =new File(dir,gryfile);
                            if(!gryf.exists()){
                                gryf.createNewFile();
                                FileOutputStream os = new FileOutputStream(gryf, true);
                                for (grydata a : grylist) {
                                    String s=a.x+","+a.y+","+a.z+","+a.timestamp+"\n";
                                    os.write(s.getBytes());
                                    os.flush();
                                }
                                grylist.clear();
                                os.close();
                            }
                        }
                        text.setClickable(true);
                        Intent intent=new Intent(collecting.this, retry.class);
                        startActivity(intent);
                    }
                    catch (IOException e){}
                }


            }

        };
        if(para.choose[0]==0)PPG.setVisibility(View.GONE);
        if(para.choose[1]==0)ACC.setVisibility(View.GONE);
        if(para.choose[2]==0)GRY.setVisibility(View.GONE);
        timer.start();
        this.mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        this.mMySensorEventListener = new MySensorEventListener();
        List<Sensor> list = mSensorManager.getSensorList(Sensor.TYPE_ALL);
        for (Sensor currentSensor :list) {
            Log.d(
                    "Device List",
                    "Name: " + currentSensor.getName() + " /Type_String: " + currentSensor.getStringType() + " /Type_number: " + currentSensor.getType()
            );
        }

    }
    protected void onResume() {
        super.onResume();
        if (mSensorManager == null) {
            return;
        }
        if(para.choose[1]==1){
        Sensor accelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (accelerometerSensor != null) {
            //register accelerometer sensor listener
            mSensorManager.registerListener(mMySensorEventListener, accelerometerSensor, SensorManager.SENSOR_DELAY_FASTEST);
        } else {
            Log.d(TAG, "Accelerometer sensors are not supported on current devices.");
        }}
        if(para.choose[0]==1) {
            Sensor ppgSensor = mSensorManager.getDefaultSensor(PPG_SENSOR);
            if (ppgSensor != null) {
                //register ppg sensor listener
                mSensorManager.registerListener(mMySensorEventListener, ppgSensor, SensorManager.SENSOR_DELAY_FASTEST);
            } else {
                Log.d(TAG, "PPG sensors are not supported on current devices.");
            }
        }

        if(para.choose[2]==1){
            Sensor gyroscopeSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
        if (gyroscopeSensor != null) {
            //register gyroscope sensor listener
            mSensorManager.registerListener(mMySensorEventListener, gyroscopeSensor, SensorManager.SENSOR_DELAY_FASTEST);
        } else {
            Log.d(TAG, "Gyroscope sensors are not supported on current devices.");
        }}
        Log.d("",mSensorManager.toString());

    }


    protected void onPause() {
        Log.d("","acc: "+count1+"  gry: "+count2+" ppg: "+count3);
        super.onPause();

        if (mSensorManager == null) {
            return;
        }
        //unregister all listener
        mSensorManager.unregisterListener(mMySensorEventListener);
    }



    private class MySensorEventListener implements SensorEventListener {
        @Override
        public void onSensorChanged(SensorEvent event) {

            Log.d("",event.sensor.getType()+"");
            if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                count1++;
                mAccelerometerReading = event.values;
                accdata a=new accdata();
                a.x=event.values[0];
                a.y=event.values[1];
                a.z=event.values[2];
                a.timestamp=event.timestamp;
                acclist.add(a);
                Log.d(TAG, "accelerometer data[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + ",time:"+event.timestamp+"]");
                ACC.setText("ACC\n[x:" +String.format("%.3f", event.values[0])  + ", y:" + String.format("%.3f", event.values[1]) + ", z:" + String.format("%.3f", event.values[2])+ "]");
            }  else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
                count2++;
                grydata a=new grydata();
                a.x=event.values[0];
                a.y=event.values[1];
                a.z=event.values[2];
                a.timestamp=event.timestamp;
                grylist.add(a);
                Log.d(TAG, "gyroscope data[x:" + event.values[0] + ", y:" + event.values[1] + ", z:" + event.values[2] + "]");
                GRY.setText("GRY\n[x:" + String.format("%.3f", event.values[0])+ ", y:" + String.format("%.3f", event.values[1]) + ", z:" + String.format("%.3f", event.values[2]) + "]");
            }else if (event.sensor.getType() == PPG_SENSOR) {
                count3++;
                ppgdata a=new ppgdata();
                a.Green=event.values[0];
                a.Red=event.values[1];
                a.timestamp=event.timestamp;
                ppglist.add(a);
                Log.d(TAG, "PPG data[x:" + event.values[0] + ", y:" + event.values[1] + "]");
                PPG.setText("PPG\n[Green:" +  event.values[0]+ "\n Red:" + event.values[1] + "]");
            }

        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            Log.d(TAG, "onAccuracyChanged:" + sensor.getType() + "->" + accuracy);
        }

    }

}